#pragma once

#include "CoreMinimal.h"
#include "ReplicationGraphTypes.h"
#include "Define\LineReplicationType.h"
#include "LineReplicationGraphComponent.generated.h"

class ULRG_Node_GridCell;
class ACMPlayerController;

UCLASS(Blueprintable, ClassGroup=(LineReplicationGraph), meta=(BlueprintSpawnableComponent))
class LINEREPLICATIONGRAPH_API ULineReplicationGraphComponent : public UActorComponent
{
	GENERATED_BODY()

	friend class ULineReplicationGraph;
public:
	static ULineReplicationGraphComponent* Get(const AActor* Owner);
	static ULineReplicationGraphComponent* Create(AActor* Owner);
protected:
	virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
	virtual void BeginPlay() override;
public:
	UFUNCTION(BlueprintNativeEvent)
	bool CanBeVisible(const TSet<FName>& VisibleLines);
	virtual bool CanBeVisible_Implementation(const TSet<FName>& VisibleLines);
public:
	UFUNCTION(BlueprintCallable)
	void SetReplicationType(ELineReplicationType InType);
	UFUNCTION(BlueprintCallable)
	const FName& GetCurrentLine() const {return CurrentLine;}
	UFUNCTION(BlueprintCallable)
	ELineReplicationType GetReplicationType() const {return ReplicationType;}
	UFUNCTION(BlueprintCallable)
	void SetWorldLocation(const FVector& Location) {WorldLocation = Location;}
	UFUNCTION(BlueprintCallable)
	const FVector& GetWorldLocation() const {return WorldLocation;}
	UFUNCTION(BlueprintCallable)
	const TMap<int32, ULRG_Node_GridCell*>& GetInfluenceCells() {return InfluenceCellMap;}
	UFUNCTION(BlueprintCallable)
	void SetInfluenceCells(const TMap<int32, ULRG_Node_GridCell*>& Value) {InfluenceCellMap = Value;}
	UFUNCTION(BlueprintCallable)
	void UpdateLocationCell(ULRG_Node_GridCell* Cell);
public:
	UFUNCTION(BlueprintCallable)
	void SetLine(const FName& LineName);
public:
	const FClassReplicationInfo& GetClassReplicationInfo() const;
	FNewReplicatedActorInfo& GetNewReplicatedActorInfo();
protected:
	void OnAddToNetwork();
	void OnRemoveFromNetwork();
protected:
	void SetReplicationInfo(FGlobalActorReplicationInfo& InReplicationInfo);
	void SetNewReplicatedActorInfo(const FNewReplicatedActorInfo& InNewReplicatedActorInfo);
protected:
	UPROPERTY(Replicated, BlueprintReadOnly, VisibleAnywhere, Category = Info)
	ELineReplicationType ReplicationType = ELineReplicationType::NotRouted;
	UPROPERTY(Replicated, BlueprintReadOnly, VisibleAnywhere, Category = Info)
	FName CurrentLine;	//当前所处的线
protected:
	UPROPERTY(Transient)
	ULRG_Node_GridCell* CurrentLocationCell = nullptr;	//当前所在格子
	UPROPERTY(Transient)
	TArray<ULRG_Node_GridCell*> RecordCaredCells;		//记录受影响的格子
	UPROPERTY(Transient)
	FVector RecordLocation = FVector();					//记录上一次的位置
	UPROPERTY(Transient)
	int32 LastPreReplicationFrame = 0;
	UPROPERTY(Transient)
	FVector WorldLocation = FVector();
	UPROPERTY(Transient)
	FClassReplicationInfo ReplicationSetting;			//同步配置
	UPROPERTY(Transient)
	TMap<int32, ULRG_Node_GridCell*> InfluenceCellMap;	//影响到的GridCell,用于Actor被移动时的通知
	UPROPERTY(Transient)
	ULRG_Node_GridCell* LocationCell = nullptr;	//位置所在的Cell

	FGlobalActorReplicationInfo* ReplicationInfo;
	FNewReplicatedActorInfo* NewReplicatedActorInfo;
};